package cn.com.bluemoon.daps.sync.service.impl;

import cn.com.bluemoon.daps.sync.base.CompareResult;
import cn.com.bluemoon.daps.sync.base.SqlCompareResult;
import cn.com.bluemoon.daps.sync.core.sync.sql.mysql.datatype.DataTypeHelper;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.ast.SQLDataType;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableItem;
import com.alibaba.druid.sql.ast.statement.SQLAlterTableStatement;
import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlAlterTableChangeColumn;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 由于获取元数据和模型数据中已经对整型类型数据进行了处理（忽略该类型的长度（mysql版本差异）
 *
 * @author Jarod.Kong
 */
@Slf4j
@Component
public class AlterTableIntegerTypeHandler extends AlterTableFieldModifySyncStatusBaseHandler {

    @Override
    public boolean matchAlterTableField(String tableName, CompareResult<SqlCompareResult> fieldCompare, String fieldAlterSql) {
        return parseStatements0(tableName, fieldAlterSql);
    }

    private boolean parseStatements0(String tableName, String sql) {
        try {
            SQLAlterTableStatement statement = parseAlterStats(sql, DbType.mysql);
            if (statement == null) {
                return false;
            }
            // 表中sqls都符合整型类型，长度为空的情况可以强制修改
            List<SQLAlterTableItem> statementItems = statement.getItems();
            if (statementItems.isEmpty()) {
                log.info("获取修改表语句的item项为空，结束");
                return false;
            }
            boolean allMatchAlterTableChangeCol = statementItems.stream().allMatch(m -> m instanceof MySqlAlterTableChangeColumn);
            if (!allMatchAlterTableChangeCol) {
                log.info("当前修改表不都是修改字段语句，结束");
                return false;
            }
            List<MySqlAlterTableChangeColumn> changeColumns = statementItems.stream()
                    .filter(m -> m instanceof MySqlAlterTableChangeColumn)
                    .map(m -> (MySqlAlterTableChangeColumn) m)
                    .filter(m -> {
                        SQLColumnDefinition newColDef = m.getNewColumnDefinition();
                        SQLDataType dataType = newColDef.getDataType();
                        return (DataTypeHelper.isIntegerType((dataType.getName().toLowerCase())) &&
                                (dataType.getArguments() == null || dataType.getArguments().isEmpty()));
                    })
                    .collect(Collectors.toList());
            if (statementItems.size() == changeColumns.size()) {
                log.warn("修改字段符合强制更改规则，sql=>{}，允许修改表{}状态", sql, tableName);
                return true;
            }
            log.info("修改字段不符合强制更改规则，不可修改状态");
            return false;
        } catch (Exception e) {
            log.error("sql=>{},解析失败！", sql, e);
            return false;
        }
    }

}
